/**
// 屏幕显示处理
**/

#include "nrf_gfx.h"
//#include "nrf52_dk.h"
#include "app_util_platform.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "boards.h"
#include "app_error.h"
#include <string.h>


#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "ble_date_time.h"

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"

#include "lv_obj.h"
#include "lv_label.h"
#include "lv_img.h"
#include "lv_disp.h"

#include "m_data_handle.h"

#define GRAY            0xC618
#define RED             0x00F8
#define BLUE            0x001F

#define COLOR_DATE              0xC5EA
#define COLOR_TIME              0xC5EA
#define COLOR_HEART             0xC5EA
#define COLOR_CAL               0x64F7
#define COLOR_DIS               0xAA3D
#define COLOR_STEP              0x67FD

#define COLOR_BAT_PER           0xAA3D


#define LINE_STEP       10

#define CIRCLE_RADIUS   10
#define CIRCLE_STEP     ((2 * CIRCLE_RADIUS) + 1)

#define BORDER          2





#define IMG_X_BL_RB     32
#define IMG_Y_BL_RB     20
#define IMG_X_BL_PAD    72
#define IMG_Y_BL_PAD    20
#define IMG_X_BAT       120
#define IMG_Y_BAT       25

#define BAT_PER_X       156
#define BAT_PER_Y       22

#define IMG_X_EXERCISE          16
#define IMG_X_DATE              128
#define IMG_Y_DATE              120
#define IMG_X_TIME_COLON1       48
#define IMG_X_TIME_COLON2       (IMG_X_TIME_COLON1 + 64)
#define IMG_Y_TIME_COLON        60

#define IMG_X_HEART     20
#define IMG_Y_HEART     190
#define IMG_X_STEP      20
#define IMG_Y_STEP      255
#define IMG_X_DIS       20
#define IMG_Y_DIS       320


#define IMG_HEIGHT_HEART        41
#define IMG_WIDTH_HEART         40
#define IMG_HEIGHT_STEP         41
#define IMG_WIDTH_STEP          40
#define IMG_HEIGHT_DIS          41
#define IMG_WIDTH_DIS           40
#define IMG_HEIGHT_BL_RB        21
#define IMG_WIDTH_BL_RB         28
#define IMG_HEIGHT_BL_PAD       21
#define IMG_WIDTH_BL_PAD        28
#define IMG_HEIGHT_BAT_FULL     13
#define IMG_WIDTH_BAT_FULL      28
#define IMG_HEIGHT_BAT_HIGH     13
#define IMG_WIDTH_BAT_HIGH      28
#define IMG_HEIGHT_BAT_MID      13
#define IMG_WIDTH_BAT_MID       28
#define IMG_HEIGHT_BAT_LOW      13
#define IMG_WIDTH_BAT_LOW       28
#define IMG_HEIGHT_BAT_CHG      13
#define IMG_WIDTH_BAT_CHG       28

#define BAT_CHAR_HEIGHT         16
#define BAT_CHAR_WIDTH          8


#pragma pack(1)

typedef enum
{
	img_heart       = 0,    //心率图片
	img_distance,           //距离图片
	img_step,               //步数图片
	img_blue_rb,            //蓝牙图标-跑步豆
	img_blue_pad,           //蓝牙图标-pad
	img_bat_low,            //低电量图标
	img_bat_mid,            //中电量图标
	img_bat_high,           //高电量图标
	img_bat_full,           //高电量图标
	img_bat_chg,            //充电图标
	img_bat_chg_full,       //充电满图标

    img_max,                //            

}Img_index_t;


typedef struct
{
    uint8_t         u8Img_index;        //图片索引编号
    uint16_t        u16height;          //图片高度
    uint16_t        u16width;           //图片宽度
    
    uint32_t        u32addr;            //在flash中的存储位置
    uint32_t        u32size;            //大小

    const uint8_t*  pImg_buf;
}Img_mng_t;

//专门用于显示电量
typedef struct
{
    uint8_t         u8Char_index;       //符号索引编号
    uint16_t        u16height;          //符号高度
    uint16_t        u16width;           //符号宽度

    const uint8_t*  pChar_buf;
}Bat_char_t;

#pragma pack()

extern const unsigned char gImage_heart[];
extern const unsigned char gImage_step[];
extern const unsigned char gImage_distance[];
extern const unsigned char gImage_bl_pad[];
extern const unsigned char gImage_bl_rb[];
extern const unsigned char gImage_bat_full[];
extern const unsigned char gImage_bat_high[];
extern const unsigned char gImage_bat_mid[];
extern const unsigned char gImage_bat_low[];
extern const unsigned char gImage_bat_chg[];
extern const unsigned char gImage_bat_chg_full[];

extern char* exercise_name[];

Img_mng_t img_manage_info[] =
{
    {
        .u8Img_index    = img_heart,
        .u16height      = IMG_HEIGHT_HEART,
        .u16width       = IMG_WIDTH_HEART,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_heart,
    },

    {
        .u8Img_index    = img_distance,
        .u16height      = IMG_HEIGHT_DIS,
        .u16width       = IMG_WIDTH_DIS,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_distance,
    },

    {
        .u8Img_index    = img_step,
        .u16height      = IMG_HEIGHT_STEP,
        .u16width       = IMG_WIDTH_STEP,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_step,
    },

    {
        .u8Img_index    = img_blue_rb,
        .u16height      = IMG_HEIGHT_BL_RB,
        .u16width       = IMG_WIDTH_BL_RB,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_bl_rb,
    },

    {
        .u8Img_index    = img_blue_pad,
        .u16height      = IMG_HEIGHT_BL_PAD,
        .u16width       = IMG_WIDTH_BL_PAD,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_bl_pad,
    },

    {
        .u8Img_index    = img_bat_low,
        .u16height      = IMG_HEIGHT_BAT_LOW,
        .u16width       = IMG_WIDTH_BAT_LOW,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_bat_low,
    },

    {
        .u8Img_index    = img_bat_mid,
        .u16height      = IMG_HEIGHT_BAT_MID,
        .u16width       = IMG_WIDTH_BAT_MID,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_bat_mid,
    },

    {
        .u8Img_index    = img_bat_high,
        .u16height      = IMG_HEIGHT_BAT_HIGH,
        .u16width       = IMG_WIDTH_BAT_HIGH,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_bat_high,
    },

    {
        .u8Img_index    = img_bat_full,
        .u16height      = IMG_HEIGHT_BAT_HIGH,
        .u16width       = IMG_WIDTH_BAT_HIGH,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_bat_full,
    },
    
    {
        .u8Img_index    = img_bat_chg,
        .u16height      = IMG_HEIGHT_BAT_CHG,
        .u16width       = IMG_WIDTH_BAT_CHG,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_bat_chg,
    },

    {
        .u8Img_index    = img_bat_chg_full,
        .u16height      = IMG_HEIGHT_BAT_CHG,
        .u16width       = IMG_WIDTH_BAT_CHG,
        .u32addr        = 0x0,
        .u32size        = 0x0,
        .pImg_buf       = gImage_bat_chg_full,
    },
};

//数字 0
uint8_t map_0[] = 
{
    /*--  文字:  0  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,
};
//数字 1
uint8_t map_1[] = 
{
    /*--  文字:  1  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00,
};
//数字 2
uint8_t map_2[] = 
{
    /*--  文字:  2  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,
};
//数字 3
uint8_t map_3[] = 
{
    /*--  文字:  3  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x04,0x02,0x42,0x42,0x3C,0x00,0x00,
};
//数字 4
uint8_t map_4[] = 
{
    /*--  文字:  4  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x04,0x0C,0x0C,0x14,0x24,0x24,0x44,0x7F,0x04,0x04,0x1F,0x00,0x00,
};
//数字 5
uint8_t map_5[] = 
{
    /*--  文字:  5  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x44,0x02,0x02,0x42,0x44,0x38,0x00,0x00,
};
//数字 6
uint8_t map_6[] = 
{
    /*--  文字:  6  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x18,0x24,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x22,0x1C,0x00,0x00,
};
//数字 7
uint8_t map_7[] = 
{
    /*--  文字:  7  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x7E,0x42,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x00,0x00,
};
//数字 8
uint8_t map_8[] = 
{
    /*--  文字:  8  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,
};
//数字 9
uint8_t map_9[] = 
{
    /*--  文字:  9  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x38,0x44,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x24,0x18,0x00,0x00,
};
//字符百分号 %
uint8_t map_per[] = 
{
    /*--  文字:  %  --*/
    /*--  宋体12;  此字体下对应的点阵为：宽x高=8x16   --*/
    0x00,0x00,0x00,0x44,0xA4,0xA8,0xA8,0xB0,0x54,0x1A,0x2A,0x2A,0x4A,0x44,0x00,0x00,
};


//显示电量专用：数字0-9和‘%’
Bat_char_t g_bat_char[11] =
{
    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_0,
    },

    
    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_1,
    },

    
    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_2,
    },

    
    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_3,
    },

    
    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_4,
    },

    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_5,
    },

    
    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_6,
    },

    
    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_7,
    },

    
    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_8,
    },

    
    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_9,
    },

    {
        .u16height      = BAT_CHAR_HEIGHT,
        .u16width       = BAT_CHAR_WIDTH,
        .pChar_buf      = map_per,
    },

};






static QueueHandle_t Queue_display_msg = NULL;

static bool lcd_drv_init = false;

extern const nrf_gfx_font_desc_t orkney_24ptFontInfo;
extern const nrf_lcd_t nrf_lcd_sh8501a0;

static const nrf_gfx_font_desc_t * p_font = &orkney_24ptFontInfo;
//static const nrf_gfx_font_desc_t * p_font_time = &orkney_24ptFontInfo;
static const nrf_lcd_t * p_lcd = &nrf_lcd_sh8501a0;

extern ble_date_time_t time_local;

extern uint8_t g_heart_value;
extern uint8_t g_heart_value_update_cnt;
extern uint16_t g_step_total;    //步数
extern double g_distance_total;    //根据经纬度计算出的距离，单位米

extern bool g_ble_running_bean_connect;
extern bool g_ble_pad_connect;

extern void screen_flush_test(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);

extern void background_set(uint16_t color);
void display_hb(uint16_t hr_value);

extern uint8_t bat_get_charging_stat(void);
extern uint8_t bat_get_lev(void);
extern void lcd_display_img(uint16_t x, uint16_t y, uint16_t img_height, uint16_t img_width, uint8_t* imp_buf, uint8_t hiden);

uint16_t get_string_width(nrf_gfx_font_desc_t const * p_font, char* string)
{
    uint16_t string_width = 0;

    uint8_t i = 0;

    for (i = 0; string[i] != '\0' ; i++)
    {
        if (string[i] != '\n')
        {
            uint8_t char_idx = string[i] - p_font->startChar;
            uint16_t char_width = string[i] == ' ' ? (p_font->height / 2) : p_font->charInfo[char_idx].widthBits;

            string_width += char_width;
        }
    }

    string_width += p_font->spacePixels * (i - 1);

    return string_width;
}


static void gfx_initialization(void)
{
    nrf_gfx_init(p_lcd);
//    APP_ERROR_CHECK(nrf_gfx_init(p_lcd));
}
#if 0

static void brackground_set(void)
{
    nrf_gfx_invert(p_lcd, true);
//    nrf_gfx_background_set(p_lcd, nrf52);
    nrf_gfx_invert(p_lcd, false);
}


static void text_print(void)
{
    nrf_gfx_point_t text_start = NRF_GFX_POINT(10, nrf_gfx_height_get(p_lcd)/2);
    APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, RED, test_text, p_font, true));
}

static void screen_clear(void)
{
    background_set(0x0000);
}

static void line_draw(void)
{
    nrf_gfx_line_t my_line = NRF_GFX_LINE(0, 0, 0, nrf_gfx_height_get(p_lcd), 2);
    nrf_gfx_line_t my_line_2 = NRF_GFX_LINE(nrf_gfx_width_get(p_lcd), nrf_gfx_height_get(p_lcd), 0, nrf_gfx_height_get(p_lcd), 1);

    for (uint16_t i = 0; i <= nrf_gfx_width_get(p_lcd); i += LINE_STEP)
    {
        my_line.x_end = i;
        APP_ERROR_CHECK(nrf_gfx_line_draw(p_lcd, &my_line, RED));
    }

    my_line.x_end = nrf_gfx_width_get(p_lcd);

    for (uint16_t i = 0; i <= nrf_gfx_height_get(p_lcd); i += LINE_STEP)
    {
        my_line.y_end = (nrf_gfx_height_get(p_lcd) - i);
        APP_ERROR_CHECK(nrf_gfx_line_draw(p_lcd, &my_line, RED));
    }

    for (uint16_t i = 0; i <= nrf_gfx_height_get(p_lcd); i += LINE_STEP)
    {
        my_line_2.y_end = (nrf_gfx_height_get(p_lcd) - i);
        APP_ERROR_CHECK(nrf_gfx_line_draw(p_lcd, &my_line_2, BLUE));
    }

    my_line_2.y_end = 0;

    for (uint16_t i = 0; i <= nrf_gfx_width_get(p_lcd); i += LINE_STEP)
    {
        my_line_2.x_end = i;
        APP_ERROR_CHECK(nrf_gfx_line_draw(p_lcd, &my_line_2, BLUE));
    }
}

static void circle_draw(void)
{
    nrf_gfx_circle_t my_circle = NRF_GFX_CIRCLE(0, 0, CIRCLE_RADIUS);

    for (uint16_t j = 0; j <= nrf_gfx_height_get(p_lcd); j += CIRCLE_STEP)
    {
        my_circle.y = j;
        for (uint16_t i = 0; i <= nrf_gfx_width_get(p_lcd); i += CIRCLE_STEP)
        {
            my_circle.x = i;
            APP_ERROR_CHECK(nrf_gfx_circle_draw(p_lcd, &my_circle, BLUE, true));
        }
    }

    for (uint16_t j = CIRCLE_RADIUS; j <= nrf_gfx_height_get(p_lcd) + CIRCLE_RADIUS; j += CIRCLE_STEP)
    {
        my_circle.y = j;
        for (uint16_t i = CIRCLE_RADIUS; i <= nrf_gfx_width_get(p_lcd) + CIRCLE_RADIUS; i += CIRCLE_STEP)
        {
            my_circle.x = i;
            APP_ERROR_CHECK(nrf_gfx_circle_draw(p_lcd, &my_circle, RED, false));
        }
    }
}

static void rect_draw(void)
{
    nrf_gfx_rect_t my_rect = NRF_GFX_RECT(nrf_gfx_width_get(p_lcd) / 2,
                             nrf_gfx_height_get(p_lcd) / nrf_gfx_width_get(p_lcd),
                             nrf_gfx_height_get(p_lcd),
                             BORDER);
    nrf_gfx_rect_t my_rect_fill = NRF_GFX_RECT(nrf_gfx_width_get(p_lcd) / 2,
                                  nrf_gfx_height_get(p_lcd) / nrf_gfx_width_get(p_lcd),
                                  nrf_gfx_height_get(p_lcd),
                                  BORDER);

    nrf_gfx_rotation_set(p_lcd, NRF_LCD_ROTATE_90);

    for (uint16_t i = 0, j = 0;
        i <= (nrf_gfx_width_get(p_lcd) - (2 * BORDER)) / 2 &&
        j <= (nrf_gfx_height_get(p_lcd) - (2 * BORDER)) / 2;
        i += 6, j += 8)
    {
        my_rect.x = i;
        my_rect.y = j;
        my_rect_fill.x = i + BORDER;
        my_rect_fill.y = j + BORDER;
        my_rect.width = nrf_gfx_width_get(p_lcd) - i * 2;
        my_rect.height = nrf_gfx_height_get(p_lcd) - j * 2;
        my_rect_fill.width = nrf_gfx_width_get(p_lcd) - i * 2 - (2 * BORDER);
        my_rect_fill.height = nrf_gfx_height_get(p_lcd) - j * 2 - (2 * BORDER);

        // Draw using pseudo-random colors.
        APP_ERROR_CHECK(nrf_gfx_rect_draw(p_lcd, &my_rect, 2, ((i + j) * 10), false));
        APP_ERROR_CHECK(nrf_gfx_rect_draw(p_lcd, &my_rect_fill, 2, (UINT16_MAX - (i + j) * 10), true));
    }

    nrf_gfx_rotation_set(p_lcd, NRF_LCD_ROTATE_0);

}
#endif

//显示电量百分比
void display_bat_char(uint16_t x, uint16_t y, uint16_t char_height, uint16_t char_width, uint8_t* char_buf)
{
    //点阵字符每行使用的字节数，目前使用的字符宽度为8个点阵，所用字节固定为1
    uint8_t bytes_in_line = 1;

    uint8_t color_buf[200] = {0};
    uint16_t color_buf_size = 0;

    color_buf[0] = 0x02;
    color_buf[1] = 0x00;
    color_buf[2] = 0x2C;
    color_buf[3] = 0x00;
    color_buf_size = 4;

    uint16_t char_index = 0;

    uint8_t char_byte = 0;


    for (uint16_t i = 0; i < char_height; i++)
    {
        color_buf_size = 4;
        
        for (uint16_t j = 0; j < bytes_in_line; j++)
        {
            //点阵对应bytes索引
            char_index = i*bytes_in_line + j;
            char_byte = char_buf[char_index];
            
            for (uint8_t k = 0; k < 8; k++)
            {
                if ((1 << (7 - k)) & char_byte)
                {
                    color_buf[color_buf_size++] = COLOR_BAT_PER >> 8;
                    color_buf[color_buf_size++] = COLOR_BAT_PER;
                }
                else
                {
                    color_buf[color_buf_size++] = 0x00;
                    color_buf[color_buf_size++] = 0x00;
                }
            }
        }
        
        sh8501a0_pixel_draw_by_line(x, (y + i), (x + char_width - 1), (y + i), color_buf, color_buf_size);
    }
}

//显示电量百分比
void display_bat_per(uint16_t x, uint16_t y, uint16_t char_height, uint16_t char_width, uint8_t bat_per)
{
    //先清除旧显示
    screen_flush_test(BAT_PER_X, y, BAT_PER_X + 32 - 1, y + BAT_CHAR_HEIGHT - 1, 0);

    //电量100%
    if (100 == bat_per)
    {
        display_bat_char(BAT_PER_X, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, (uint8_t*)g_bat_char[1].pChar_buf);
        display_bat_char(BAT_PER_X + 8, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, (uint8_t*)g_bat_char[0].pChar_buf);
        display_bat_char(BAT_PER_X + 16, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, (uint8_t*)g_bat_char[0].pChar_buf);
        display_bat_char(BAT_PER_X + 24, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, (uint8_t*)g_bat_char[10].pChar_buf);
    }
    //电量>=10%
    else if (bat_per >= 10)
    {
        display_bat_char(BAT_PER_X, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, (uint8_t*)g_bat_char[bat_per/10].pChar_buf);
        display_bat_char(BAT_PER_X + 8, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, (uint8_t*)g_bat_char[bat_per%10].pChar_buf);
        display_bat_char(BAT_PER_X + 16, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, (uint8_t*)g_bat_char[10].pChar_buf);
    }
    //电量<10%
    else if (bat_per < 10)
    {
        display_bat_char(BAT_PER_X, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, (uint8_t*)g_bat_char[bat_per].pChar_buf);
        display_bat_char(BAT_PER_X + 8, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, (uint8_t*)g_bat_char[10].pChar_buf);
    }
    
}


//隐藏图片
void hide_img(uint16_t x, uint16_t y, uint16_t img_height, uint16_t img_width)
{
    lcd_display_img(x, y, img_height, img_width, NULL, true);
}

//显示图片
void display_img(uint16_t x, uint16_t y, uint16_t img_height, uint16_t img_width, uint8_t* imp_buf)
{
    lcd_display_img(x, y, img_height, img_width, imp_buf, false);
    return;
#if 0
    uint8_t tx_data[400] = {0};
    uint8_t size = 0;

    uint16_t color_index = 0;

    //逐行设置
    for (uint16_t i = 0; i < img_height; i++)
    {
        size = 0;
        tx_data[size++] = 0x02;
        tx_data[size++] = 0;
        tx_data[size++] = 0x2C;
        tx_data[size++] = 0;

        for (uint8_t j = 0; j < img_width; j++)
        {
            tx_data[size++] = imp_buf[color_index++];
            tx_data[size++] = imp_buf[color_index++];
        }
        
        sh8501a0_pixel_draw_by_line(x, (y + i), (x + img_width - 1), (y + i), tx_data, size);
    }
#endif
}

//显示数字
void display_num(uint16_t x, uint16_t y, uint16_t num, uint16_t color)
{
    uint8_t buf[25] = {0};
    nrf_gfx_point_t text_start;
    
    if (false == lcd_drv_init)
    {
        return;
    }

    screen_flush_test(x, y, 194, y + 45, 0);
    
    sprintf(buf, "%d", num);
    
    text_start.x = x;
    text_start.y = y;
    APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, color, buf, p_font, false));
}


//显示心率
void display_hb(uint16_t hr_value)
{
    uint16_t x = IMG_X_HEART + 52;
    uint16_t y = IMG_Y_HEART + 2;

    display_num(x, y, hr_value, COLOR_HEART);
}

//显示心率单位：/Min
void display_hb_uint(void)
{
}

//显示步数
void display_step(uint16_t step_value)
{
    static uint16_t step_value_last = 65535;

    //没变化不刷新
    if (step_value_last == step_value)
    {
        return;
    }

    step_value_last = step_value;
    
    uint16_t x = IMG_X_STEP + 52;
    uint16_t y = IMG_Y_STEP + 2;

    display_num(x, y, step_value, COLOR_STEP);
}


//显示步数单位：step
void display_step_uint(void)
{
}

//显示距离
void display_dis(uint16_t dis_value)
{
    static uint16_t dis_value_last = 65535;
    
    //没变化不刷新
    if (dis_value_last == dis_value)
    {
        return;
    }

    dis_value_last = dis_value;
    
    uint16_t x = IMG_X_DIS + 52;
    uint16_t y = IMG_Y_DIS + 3;

    display_num(x, y, dis_value, COLOR_DIS);
}

void display_exercise_name   (uint8_t* name, uint8_t len)
{
    uint8_t buf[10]         = {0};
    uint16_t string_width   = 0;

    nrf_gfx_point_t text_start;
   
    static uint16_t x1_name_last = 0;
    static uint16_t x2_name_last = IMG_X_DATE -30;


    screen_flush_test(x1_name_last, IMG_Y_DATE, x2_name_last, IMG_Y_DATE + 45, 0);

    if (len > 4)
    {
        len = 4;
    }
    memcpy(buf, name, len);

    sprintf((buf + len), ":");

    string_width = get_string_width(p_font, buf);

    if (string_width > (IMG_X_DATE - 30))
    {
        text_start.x = 0;
    }
    else
    {
        text_start.x = IMG_X_DATE - string_width - 30;
    }
    
    text_start.y = IMG_Y_DATE;
    APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, COLOR_DATE, buf, p_font, false));

    x1_name_last = text_start.x;
    x2_name_last = text_start.x + string_width;

    NRF_LOG_INFO("x1_name_last = %d", x1_name_last);
    NRF_LOG_INFO("string_width = %d", string_width);
}

void display_exe_progress(uint8_t current, uint8_t total)
{
    static uint8_t current_last = 0xFF;
    static uint8_t total_last = 0xFF;

    uint8_t buf[5]          = {0};
    uint16_t string_width   = 0;
    nrf_gfx_point_t text_start;

    uint16_t x = IMG_X_DATE;
    uint16_t y = IMG_Y_DATE + 3;

    if (false == lcd_drv_init)
    {
        return;
    }

    static uint16_t x1_current_last = IMG_X_DATE - 25;
    static uint16_t x2_current_last = IMG_X_DATE - 4;
    static uint16_t x1_total_last = IMG_X_DATE + 35;
    static uint16_t x2_total_last = IMG_X_DATE + 65;


    //显示当前环节
    //有更新才处理
    if (current_last != current)
    {
        current_last = current;

        screen_flush_test(x1_current_last, y, x2_current_last, y + 45, 0);

        sprintf(buf, "%u", current);
        string_width = get_string_width(p_font, buf);

        x = IMG_X_DATE - (string_width);

        text_start.x = x;
        text_start.y = y;
        APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, COLOR_TIME, buf, p_font, false));

        x1_current_last = x;
        x2_current_last = x + string_width;
    }


    //显示总环节
    //有更新才处理
    if (total_last != total)
    {
        total_last = total;
        
        screen_flush_test(x1_total_last, y, x2_total_last, y + 45, 0);

        sprintf(buf, "%u", total);
        string_width = get_string_width(p_font, buf);

        x = IMG_X_DATE + 25;
        
        text_start.x = x;
        text_start.y = y;
        APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, COLOR_TIME, buf, p_font, false));
        
        x1_total_last = x;
        x2_total_last = x + string_width;
    }
}

void display_date_Sym   (void)
{
    uint8_t buf[5] = {0};
    nrf_gfx_point_t text_start;
    
    sprintf(buf, "/");
    
    text_start.x = IMG_X_DATE;
    text_start.y = IMG_Y_DATE;
    APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, COLOR_DATE, buf, p_font, false));
}

void display_time(uint8_t time_Hour, uint8_t time_Min, uint8_t time_Sec)
{

    uint8_t buf[5]          = {0};
    uint16_t string_width   = 0;
    nrf_gfx_point_t text_start;

    uint16_t x = IMG_X_TIME_COLON1;
    uint16_t y = IMG_Y_TIME_COLON + 3;

    if (false == lcd_drv_init)
    {
        return;
    }

    static uint8_t time_hour_last   = 0xFF;
    static uint8_t time_Min_last    = 0xFF;
    static uint8_t time_sec_last    = 0xFF;

    //时间有更新才处理
    if (time_hour_last != time_Hour)
    {
        time_hour_last = time_Hour;
        
        //显示小时处理
        static uint16_t x1_hour_last = 0;
        static uint16_t x2_hour_last = IMG_X_TIME_COLON1 - 5;
        
        screen_flush_test(x1_hour_last, y, x2_hour_last, y + 45, 0);

        sprintf(buf, "%u", time_Hour);

        string_width = get_string_width(p_font, buf);

        x = IMG_X_TIME_COLON1 - (string_width + 5);

        text_start.x = x;
        text_start.y = y;
        APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, COLOR_TIME, buf, p_font, false));

        x1_hour_last = x;
        x2_hour_last = x + string_width;
    }

    //时间有更新才处理
    if (time_Min_last != time_Min)
    {
        time_Min_last = time_Min;
        
        //显示分钟处理
        static uint16_t x1_min_last = IMG_X_TIME_COLON1 + 10;
        static uint16_t x2_min_last = 194;
        screen_flush_test(x1_min_last, y, x2_min_last, y + 45, 0);

        sprintf(buf, "%.2u", time_Min);

        string_width = get_string_width(p_font, buf);

        x = IMG_X_TIME_COLON1 + 13;
        
        text_start.x = x;
        text_start.y = y;
        APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, COLOR_TIME, buf, p_font, false));

        x1_min_last = x;
        x2_min_last = x + string_width;
    }
    
    //时间有更新才处理
    if (time_sec_last != time_Sec)
    {
        time_sec_last = time_Sec;
        
        //显示分钟处理
        static uint16_t x1_sec_last = IMG_X_TIME_COLON2 + 10;
        static uint16_t x2_sec_last = 194;
        screen_flush_test(x1_sec_last, y, x2_sec_last, y + 45, 0);

        sprintf(buf, "%.2u", time_sec_last);

        string_width = get_string_width(p_font, buf);

        x = IMG_X_TIME_COLON2 + 13;
        
        text_start.x = x;
        text_start.y = y;
        APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, COLOR_TIME, buf, p_font, false));

        x1_sec_last = x;
        x2_sec_last = x + string_width;
    }
    
}

void display_time_colon(void)
{
    uint8_t buf[5] = {0};
    nrf_gfx_point_t text_start;
    
    sprintf(buf, ":");
    
    text_start.x = IMG_X_TIME_COLON1;
    text_start.y = IMG_Y_TIME_COLON;
    APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, COLOR_TIME, buf, p_font, false));

    text_start.x = IMG_X_TIME_COLON2;
    APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, COLOR_TIME, buf, p_font, false));
}

void display_time_am_pm(uint16_t x, uint16_t y)
{
    uint8_t buf[25] = {0};
    nrf_gfx_point_t text_start;

    if (false == lcd_drv_init)
    {
        return;
    }

    sprintf(buf, "AM");
    
    text_start.x = x;
    text_start.y = y;
    APP_ERROR_CHECK(nrf_gfx_print(p_lcd, &text_start, RED, buf, p_font, false));
}

void display_battery_lev(uint8_t bat_lev)
{
}

void lcd_display_init(void)
{
    gfx_initialization();
    
    lcd_drv_init = true;

//    nrf_delay_ms(1000);

    background_set(0x0000);
//return;
#if 0
    display_time_am_pm(10, 10);

    display_battery_img(130, 20);
#endif

    //显示日期
    display_exercise_name("xxxx", 4);
    display_exe_progress(0, 0);
    display_date_Sym();

    //显示时间
    display_time(time_local.hours, time_local.minutes, 0);
    display_time_colon();

#if 0
    //跑步豆蓝牙图标
    display_img(IMG_X_BL_RB, IMG_Y_BL_RB, IMG_HEIGHT_BL_RB, IMG_WIDTH_BL_RB, (uint8_t*)gImage_bl_rb);

    //pad蓝牙图标
    display_img(IMG_X_BL_PAD, IMG_Y_BL_PAD, IMG_HEIGHT_BL_PAD, IMG_WIDTH_BL_PAD, (uint8_t*)gImage_bl_pad);

    //电量图标
    display_img(IMG_X_BAT, IMG_Y_BAT, IMG_HEIGHT_BAT_MID, IMG_WIDTH_BAT_MID, (uint8_t*)gImage_bat_mid);
#endif

    //心率图标
    display_img(IMG_X_HEART, IMG_Y_HEART, IMG_HEIGHT_HEART, IMG_WIDTH_HEART, (uint8_t*)gImage_heart);

    //显示心率
    display_hb(0);
    
    //步数图标
    display_img(IMG_X_STEP, IMG_Y_STEP, IMG_HEIGHT_STEP, IMG_WIDTH_STEP, (uint8_t*)gImage_step);

    //显示步数
    display_step(0);

    //距离图标
    display_img(IMG_X_DIS, IMG_Y_DIS, IMG_HEIGHT_DIS, IMG_WIDTH_DIS, (uint8_t*)gImage_distance);
    
    //显示距离
    display_dis(0);


}

//*****************************************************************************
// * 函 数 名  : task_display_Message_Send
// * 函数功能  : 刷屏模块发送消息处理函数
// * 输入参数  :	 无
// * 输出参数  : 无
// * 返 回 值  : 无
//*****************************************************************************/
void task_display_Message_Send(uint8_t Message)
{
//    NRF_LOG_INFO("task_display_Message_Send");
    //发出消息
    if (NULL != Queue_display_msg)
    {
        xQueueSend(Queue_display_msg, &Message, 0);
    }
}


//*****************************************************************************
// * 函 数 名  : task_display_handle
// * 函数功能  : 刷屏任务处理
// * 输入参数  :	 无
// * 输出参数  : 无
// * 返 回 值  : 无
//*****************************************************************************/
void task_display_handle(void * arg)
{
    /*******************************************************************************************/
    //目前屏幕显示内容比较简单，暂时只使用周期性的刷新处理，后续再根据需要更改刷新处理方式
    /*******************************************************************************************/
    
    UNUSED_PARAMETER(arg);

    bool ble_rb_connect_last    = false;
    bool ble_pad_connect_last   = false;
    uint8_t charging_last       = 0;
    uint8_t charging_stat       = 0;
    uint8_t bat_lev             = bat_get_lev();
    uint8_t bat_lev_last        = 0;

    uint8_t bat_per             = bat_get_percent();
    uint8_t bat_per_last        = 0;

    uint8_t heart_last          = 0;
    uint8_t exe_id_last         = 0;

    uint8_t EventMsg = 0;
    
#if 0
    lv_init();
    lv_port_disp_init();

    lv_display_creat();
#endif
    Queue_display_msg = xQueueCreate(2, sizeof(uint8_t));

    while (1)
    {
        if (pdPASS  == xQueueReceive(Queue_display_msg, &EventMsg, 100/portTICK_PERIOD_MS))
        {
//            NRF_LOG_INFO("Queue_display_msg: EventMsg = %d", EventMsg);

            if (0xAA == EventMsg)
            {
                if (g_heart_value)
                {
                    //超过5S没有更新就清零心率值
                    g_heart_value_update_cnt++;
                    
                    if (g_heart_value_update_cnt > 20)
                    {
                        g_heart_value = 0;
                        g_heart_value_update_cnt = 0;
                    }
                }
                
                //刷新心率显示
                if (heart_last != g_heart_value)
                {
                    display_hb(g_heart_value);
                    
                    heart_last = g_heart_value;
                }
        

                m_bracelet_state.train_sec;

                uint8_t hour    = m_bracelet_state.train_sec / 3600;
                uint8_t min     = (m_bracelet_state.train_sec % 3600) / 60;
                uint8_t sec     = m_bracelet_state.train_sec % 60;

                display_time(hour, min, sec);

                //训练计划有更新，更新显示
                display_exe_progress(m_bracelet_state.train_cur_step, m_bracelet_state.train_all_step);

                if (exe_id_last != m_bracelet_state.train_id)
                {
                    char* exe_name = exercise_name[m_bracelet_state.train_id+1];

                    display_exercise_name(exe_name, strlen(exe_name));
                    
                    exe_id_last = m_bracelet_state.train_id;
                }
                
                display_step(g_step_total);
//                display_step(g_train_step);
                display_dis((uint16_t)g_distance_total);
//                display_dis((uint16_t)g_train_distance);
                

                //跑步豆蓝牙图标刷新
                if (ble_rb_connect_last != g_ble_running_bean_connect)
                {
                    //显示跑步豆蓝牙图标
                    if (g_ble_running_bean_connect)
                    {
                        display_img(IMG_X_BL_RB, IMG_Y_BL_RB, IMG_HEIGHT_BL_RB, IMG_WIDTH_BL_RB, (uint8_t*)gImage_bl_rb);
                    }
                    //隐藏跑步豆蓝牙图标
                    else
                    {
                        hide_img(IMG_X_BL_RB, IMG_Y_BL_RB, IMG_HEIGHT_BL_RB, IMG_WIDTH_BL_RB);
                    }
                    ble_rb_connect_last = g_ble_running_bean_connect;
                }

                //pad蓝牙图标刷新
                if (ble_pad_connect_last != g_ble_pad_connect)
                {
                    //显示pad蓝牙图标
                    if (g_ble_pad_connect)
                    {
                        display_img(IMG_X_BL_PAD, IMG_Y_BL_PAD, IMG_HEIGHT_BL_PAD, IMG_WIDTH_BL_PAD, (uint8_t*)gImage_bl_pad);
                    }
                    //隐藏pad蓝牙图标
                    else
                    {
                        hide_img(IMG_X_BL_PAD, IMG_Y_BL_PAD, IMG_HEIGHT_BL_PAD, IMG_WIDTH_BL_PAD);
                    }
                        
                    ble_pad_connect_last = g_ble_pad_connect;
                }
                //电量图标刷新
                charging_stat = bat_get_charging_stat();
                #if 0
                NRF_LOG_INFO("charging_stat = %d", charging_stat);
                NRF_LOG_INFO("charging_last = %d", charging_last);
                NRF_LOG_INFO("bat_lev_last = %d", bat_lev_last);
                NRF_LOG_INFO("bat_lev = %d", bat_lev);
                #endif
                if (charging_stat)
                {
                    if (charging_stat != charging_last)
                    {
                        //充满电
                        if (2 == charging_stat)
                        {
                            display_img(IMG_X_BAT, IMG_Y_BAT, IMG_HEIGHT_BAT_MID, IMG_WIDTH_BAT_MID, (uint8_t*)img_manage_info[img_bat_chg_full].pImg_buf);
                        }
                        else
                        {
                            display_img(IMG_X_BAT, IMG_Y_BAT, IMG_HEIGHT_BAT_MID, IMG_WIDTH_BAT_MID, (uint8_t*)img_manage_info[img_bat_chg].pImg_buf);
                        }
                    }

                }
                else
                {
                    bat_lev = bat_get_lev();
                    
                    if (charging_last)
                    {
                        display_img(IMG_X_BAT, IMG_Y_BAT, IMG_HEIGHT_BAT_MID, IMG_WIDTH_BAT_MID, (uint8_t*)gImage_bat_mid);
                    }
                    else if (bat_lev_last != bat_lev)
                    {
                        display_img(IMG_X_BAT, IMG_Y_BAT, IMG_HEIGHT_BAT_MID, IMG_WIDTH_BAT_MID, (uint8_t*)img_manage_info[img_bat_low + bat_lev - 1].pImg_buf);
                    }
                    bat_lev_last = bat_lev;
                }
                charging_last = charging_stat;

                bat_per = bat_get_percent();
//                NRF_LOG_INFO("bat_per = %d, bat_per_last = %d", bat_per, bat_per_last);

                //刷新电量显示
                if (bat_per_last != bat_per)
                {
                    display_bat_per(BAT_PER_X, BAT_PER_Y, BAT_CHAR_HEIGHT, BAT_CHAR_WIDTH, bat_per);

                    bat_per_last = bat_per;
                }
            }
        }
        
        EventMsg = 0;

//        lv_task_handler();
        
    }
}


